#include "../Helix/View/OpenGL/OpenGLSupport.h"

#include "../Helix/Helix.h"
#include "../Helix/Application.h"
#include "../Helix/Window.h"
#include "../Helix/Input.h"
#include "../Helix/DirectInput.h"
#include "../Helix/Timer.h"
#include "../Helix/HighPerformanceTimer.h"
#include "Game.h"											// Header File For Derived Application Class
#include <math.h>

using namespace helix;

int WINAPI WinMain(	HINSTANCE	hInstance,			// Instance
					HINSTANCE	hPrevInstance,		// Previous Instance
					LPSTR		lpCmdLine,			// Command Line Parameters
					int			nCmdShow)			// Window Show State
{
	MSG		msg;									// Windows Message Structure
	bool	fullScreen=true;						// Bool Variable To start in fullscreen

	// Ask The User Which Screen Mode They Prefer
	if (MessageBox(NULL,"Would You Like To Run In Fullscreen Mode?", "Start FullScreen?",MB_YESNO|MB_ICONQUESTION)==IDNO)
	{
		fullScreen=false;							// Windowed Mode
	}

	//get an instance of the Helix application
	Application *app=Application::getInstance();

	//set the log file to output to
	app->Log().setLog("helix.log");
	
	//initialize the application by specifying a window type and setting the window parameters
	if(!app->initApp(Application::OPEN_GL_WINDOW,"Helix",800,600,32,45.0f,fullScreen))
	{
		app->Log().Error("Initialization of the application failed.");
			//deinitialize everything
		app->destroyApp();
		return (msg.wParam);
	}


	app->Log().Println("Window Created, starting main game loop.");

	//create a new input object

	Timer *timer;
	Input *input;
	Window *wind;

	Game *game;
	

	timer=(Timer*) new HighPerformanceTimer();
	wind=app->window();
	input=(Input*) new DirectInput();
	((DirectInput*)input)->initialize(wind->getHINSTANCE(),wind->HWND());

	game=new Game();

	app->setTimer(timer);
	app->setInput(input);
	app->setRenderer(game);
	app->setUpdater(game);

	//Disable vsync
	app->window()->getRenderHelper()->setVSync(false);

	//run the application
	while(app->runMainLoop(&msg));

	app->Log().Println("Game loop ended.  Shutting down Helix application...");

	//deinitialize everything
	app->destroyApp();

	return (msg.wParam);
}


void Game::renderScene()
{
	glMatrixMode(GL_MODELVIEW);
	glClearColor(1.0,1.0,1.0,1.0);
	glClear(GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT);
			//this is where everything in the main rendering loop should go
	glColor3f(1.0,1.0,1.0);
	glLineWidth(5);
	glLoadIdentity();

	glEnable(GL_LINE_SMOOTH);
	glEnable(GL_TEXTURE_2D);
	


	glTranslatef(0.0,0.0,-1.5);
//	glRotatef(45.0,1.0,0.0,0.0);

	glBindTexture(GL_TEXTURE_2D,texturePNG->getId());
	glBegin(GL_QUADS);
		glTexCoord2f(0.0,0.0);
		glVertex3f(-4.0,-4.0,-5);
		glTexCoord2f(4.0,0.0);
		glVertex3f(4.0,-4.0,-5);
		glTexCoord2f(4.0,4.0);
		glVertex3f(4.0,4.0,-5);
		glTexCoord2f(0.0,4.0);
		glVertex3f(-4.0,4.0,-5);
	glEnd();

	glDisable(GL_TEXTURE_2D);

	glBegin(GL_LINES);
	for(int i=0;i<numPoints-1;i++)
	{
		int j = findClosest(i);
		if( j != -1)
		{
			glColor3f(1.0f - (float)i / (float)numPoints,0.25f,0.5f);
			glVertex3f(getX(i),getY(i),0.0);
			glColor3f(1.0f - (float)j / (float)numPoints,0.25f,0.5f);
			glVertex3f(getX(j),getY(j),0.0);
		}
	}
	glEnd();

	glFlush();
}

void Game::update(double dSeconds)
{
	for(int i=0;i<numPoints;i++){
		rot[i]+=((float)(i+1)) * (0.002f)*(float)dSeconds;
	}

	if((int)(rot[0]*100.0)%100==0)
		Application::getInstance()->Log().Println("fps= %f, rot=%f",1.0/dSeconds,rot[0]);

	Log log=Application::getInstance()->Log();

}

int Game::findClosest(int index){
	float curdist = 100.0f;
	int curInd = index+1;
	float thisPosX = getX(index);
	float thisPosY = getY(index);
	for(int i=curInd;i<curInd+50;i++){
		float curPosX = getX(i);
		float curPosY = getY(i);
		float x = curPosX-thisPosX;
		float y = curPosY-thisPosY;
		float dist = x*x+y*y;
		if(dist < curdist){
			curdist = dist;
			curInd = i;
		}
	}

	if(curdist >= 0.25f)
		curInd = -1;

	return curInd;
}

float Game::getX(int index){
	return rad[index] * (float)cos(double(rot[index]));
}

float Game::getY(int index){
	return rad[index] * (float)sin(double(rot[index]));
}